package ksj.common.tasks;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.domain.EntityScan;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;

import bean.Schedules;
import ksj.common.utils.Constants;
import ksj.common.utils.net.GenericServiceConsumer;

@EntityScan(basePackages = { "bean" })
public class ScheduleCheckBeat implements Job {
	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {

		System.out.println("Checking schedules...");
		// List<Object[]> scheules = schedulesDAO.getAllSchedules();
		// System.out.println(scheules.size());

		JSONObject result = GenericServiceConsumer.consumeServiceGET("/getSchedules", "localhost", 8833, "");
		Object object = result.get("entity");
		JSONObject responseob = new JSONObject(object.toString());
		JSONArray response = (JSONArray) responseob.get("response");
		Gson gson = new Gson();
		TypeToken<List<Schedules>> token = new TypeToken<List<Schedules>>() {
		};
		List<Schedules> schedules = gson.fromJson(response.toString(), token.getType());
		System.out.println(schedules.size());
		for (Schedules schedule : schedules) {
			String monthDay = schedule.getMonth_day();
			String weekDay = schedule.getWeek_day();
			String startTime = schedule.getStart_time();
			String[] hoursMinsSecs = startTime.split(":");

			if (Constants.TASK_SCHEDULE_TYPE_MONTHLY.equals(schedule.getSchedule_type())) {
				String[] monthdays = monthDay.split(",");
				if (Constants.TASK_TYPE_RABBITMQ.equals(schedule.getTask_type())) {
					for (String monthday : monthdays) {
						JobDetail job = JobBuilder.newJob(RabbitMQTask.class)
								.withIdentity(
										schedule.getId() + "_" + schedule.getTask_name() + "_" + monthday + "_Job",
										Constants.TASK_TYPE_RABBITMQ)
								.build();
						job.getJobDataMap().put(RabbitMQTask.SCHEDULE, schedule);

						Trigger trigger = TriggerBuilder.newTrigger()
								.withIdentity(
										schedule.getId() + "_" + schedule.getTask_name() + "_" + monthday + "_Trigger",
										Constants.TASK_TYPE_RABBITMQ)
								.startNow()
								.withSchedule(CronScheduleBuilder.monthlyOnDayAndHourAndMinute(
										Integer.parseInt(monthday.replace("#", "")), Integer.parseInt(hoursMinsSecs[0]),
										Integer.parseInt(hoursMinsSecs[1])))
								.build();
						try {
							Scheduler scheduler = new StdSchedulerFactory().getScheduler();

							scheduler.start();

							scheduler.scheduleJob(job, trigger);
						} catch (Exception e) {
							// scheduler.deleteJob(job.getKey());
							System.out.println(schedule.getId() + " Already Running");
						}
					}
				}
			}
			if (Constants.TASK_SCHEDULE_TYPE_WEEKLY.equals(schedule.getSchedule_type())) {
				String[] weekDays = weekDay.split(",");
				for (String weekday : weekDays) {
					JobDetail job = JobBuilder.newJob(RabbitMQTask.class)
							.withIdentity(schedule.getId() + "_" + schedule.getTask_name() + "_" + weekday + "_Job",
									Constants.TASK_TYPE_RABBITMQ)
							.build();
					job.getJobDataMap().put(RabbitMQTask.SCHEDULE, schedule);

					Trigger trigger = TriggerBuilder.newTrigger()
							.withIdentity(schedule.getId() + "_" + schedule.getTask_name() + "_" + weekday + "_Trigger",
									Constants.TASK_TYPE_RABBITMQ)
							.startNow()
							.withSchedule(CronScheduleBuilder.weeklyOnDayAndHourAndMinute(
									Integer.parseInt(weekday.replace("#", "")), Integer.parseInt(hoursMinsSecs[0]),
									Integer.parseInt(hoursMinsSecs[1])))
							.build();
					try {
						Scheduler scheduler = new StdSchedulerFactory().getScheduler();

						scheduler.start();

						scheduler.scheduleJob(job, trigger);
					} catch (Exception e) {
						// scheduler.deleteJob(job.getKey());
						System.out.println(schedule.getId() + " Already Running");
					}
				}
			}
			if (Constants.TASK_SCHEDULE_TYPE_DAILY.equals(schedule.getSchedule_type())) {
				JobDetail job = JobBuilder.newJob(RabbitMQTask.class)
						.withIdentity(schedule.getId() + "_" + schedule.getTask_name() + "_Daily" + "_Job",
								Constants.TASK_TYPE_RABBITMQ)
						.build();
				job.getJobDataMap().put(RabbitMQTask.SCHEDULE, schedule);

				Trigger trigger = TriggerBuilder.newTrigger()
						.withIdentity(schedule.getId() + "_" + schedule.getTask_name() + "_Daily" + "_Trigger",
								Constants.TASK_TYPE_RABBITMQ)
						.startNow()
						.withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(Integer.parseInt(hoursMinsSecs[0]),
								Integer.parseInt(hoursMinsSecs[1])))
						.build();
				try {
					Scheduler scheduler = new StdSchedulerFactory().getScheduler();

					scheduler.start();

					scheduler.scheduleJob(job, trigger);
				} catch (Exception e) {
					// scheduler.deleteJob(job.getKey());
					System.out.println(schedule.getId() + " Already Running");
				}
			}
		}

	}

}
